#include "msp.h"
#include "stdint.h"

#define GPIO1 (1)
#define GPIO2 (2)
#define GPIO3 (3)
#define GPIO4 (4)
#define GPIO5 (5)
#define GPIO6 (6)
#define GPIO7 (7)
#define GPIO8 (8)
#define GPIO9 (9)
#define GPIOJ (10)

#define GPIO_PIN_0 (0)
#define GPIO_PIN_1 (1)
#define GPIO_PIN_2 (2)
#define GPIO_PIN_3 (3)
#define GPIO_PIN_4 (4)
#define GPIO_PIN_5 (5)
#define GPIO_PIN_6 (6)
#define GPIO_PIN_7 (7)

typedef enum { GPIO_PIN_RESER, GPIO_PIN_SET } GPIO_PinState_t;
typedef enum { GPIO_PIN_Output, GPIO_PIN_Input } GPIO_PinMode_t;
typedef enum { GPIO_Pull_None, GPIO_Pull_Up, GPIO_Pull_Down } GPIO_PinPull_t;

#define PORT_IN_DEVIATION ((uint32_t)&P1->IN - (uint32_t)P1)
#define PORT_OUT_DEVIATION ((uint32_t)&P1->OUT - (uint32_t)P1)
#define PORT_DIR_DEVIATION ((uint32_t)&P1->DIR - (uint32_t)P1)
#define PORT_REN_DEVIATION ((uint32_t)&P1->REN - (uint32_t)P1)
#define PORT_DS_DEVIATION ((uint32_t)&P1->DS - (uint32_t)P1)
#define PORT_SEL0_DEVIATION ((uint32_t)&P1->SEL0 - (uint32_t)P1)
#define PORT_SEL1_DEVIATION ((uint32_t)&P1->SEL1 - (uint32_t)P1)
#define PORT_IE_DEVIATION ((uint32_t)&P1->IE - (uint32_t)P1)
#define PORT_IES_DEVIATION ((uint32_t)&P1->IES - (uint32_t)P1)
#define PORT_IFG_DEVIATION ((uint32_t)&P1->IFG - (uint32_t)P1)

#define HWREG8(x) (*((volatile uint8_t *)(x)))
#define HWREG16(x) (*((volatile uint16_t *)(x)))
#define HWREG32(x) (*((volatile uint32_t *)(x)))
#define HWREG(x) (HWREG16(x))
#define HWREG8_L(x) (*((volatile uint8_t *)((uint8_t *)&x)))
#ifndef HWREG8_H
#define HWREG8_H(x) (*((volatile uint8_t *)(((uint8_t *)&x) + 1)))
#endif
#define HWREG16_L(x) (*((volatile uint16_t *)((uint16_t *)&x)))
#ifndef HWREG16_H
#define HWREG16_H(x) (*((volatile uint16_t *)(((uint16_t *)&x) + 1)))
#endif

/**
 * @brief 修改引脚模式
 *
 * @param gpio 引脚组数
 * @param pin 引脚编号
 * @param mode 引脚模式
 */
void GPIO_ModeSet(uint8_t gpio, uint8_t pin, GPIO_PinMode_t mode);
/**
 * @brief 更改引脚电平
 *
 * @param gpio 引脚组数
 * @param pin 引脚编号
 * @param mode 引脚模式
 */
void GPIO_WritePin(uint8_t gpio, uint8_t pin, GPIO_PinState_t mode);
/**
 * @brief 批量修改引脚电平
 *
 * @param gpio 引脚组数
 * @param data 二进制数据
 * @return uint8_t
 */
void GPIO_WriteAll(uint8_t gpio, uint8_t data);
/**
 * @brief 批量修改引脚模式
 *
 * @param gpio 引脚组数
 * @param data 二进制数据
 * @return uint8_t
 */
void GPIO_SetModeAll(uint8_t gpio, uint8_t data);
/**
 * @brief 翻转引脚电平
 *
 * @param gpio 引脚组数
 * @param pin 引脚编号
 * @return uint8_t
 */
void GPIO_Rolling(uint8_t gpio, uint8_t pin);
/**
 * @brief 开启引脚上/下拉
 *
 * @param gpio 引脚组数
 * @param pin 引脚编号
 * @param mode 上拉模式
 * @return uint8_t
 */
void GPIO_Pull_Set(uint8_t gpio, uint8_t pin, GPIO_PinPull_t mode);
/**
 * @brief 读取引脚电平
 *
 * @param gpio 引脚组数
 * @param pin 引脚编号
 * @return uint8_t
 */
uint8_t GPIO_InPut(uint8_t gpio, uint8_t pin);
/**
 * @brief 读取一组引脚电平
 *
 * @param gpio 引脚组数
 * @return uint8_t
 */
uint8_t GPIO_InPut_All(uint8_t gpio);
